package com.sinog.front.config;

import io.swagger.annotations.ApiImplicitParams;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.GrantType;
import springfox.documentation.service.OAuth;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.DocExpansion;
import springfox.documentation.swagger.web.ModelRendering;
import springfox.documentation.swagger.web.OperationsSorter;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
import springfox.documentation.swagger.web.TagsSorter;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @desc Swagger配置
 * @author - lzq
 * @date -
 */
@Configuration
public class SwaggerConfig {

    public static final String VERSION = "2.3.5";

    /**
     * 描述
     * @return ApiInfo
     */
    private static ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("安置帮教项目 API").version(VERSION).build();
    }

    /**
     * 描述
     * @return Docket
     */
    @Bean
    public Docket customImplementation() {
        return new Docket(DocumentationType.SWAGGER_2).select()
                                                      .apis(RequestHandlerSelectors.basePackage("com.sinog.front"))
                                                      .apis(RequestHandlerSelectors.withMethodAnnotation(ApiImplicitParams.class))
                                                      .build().apiInfo(apiInfo())
                                                      .securityContexts(Collections.singletonList(securityContext()))
                                                      .securitySchemes(Arrays.asList(securitySchema(),apiKey(),apiCookieKey()));
    }

    /**
     * 描述
     * @return SecurityScheme
     */
    @Bean
    public SecurityScheme apiKey() {
        return new ApiKey(HttpHeaders.AUTHORIZATION,"apiKey","header");
    }

    /**
     * 描述
     * @return SecurityScheme
     */
    @Bean
    public SecurityScheme apiCookieKey() {
        return new ApiKey(HttpHeaders.COOKIE,"apiKey","cookie");
    }

    /**
     * 描述
     * @return SecurityConfiguration
     */
    @Bean
    SecurityConfiguration security() {
        return SecurityConfigurationBuilder.builder().clientId("client_test").clientSecret("secret_test")
                                           .realm("test-app-realm").appName("test-app").scopeSeparator(",")
                                           .additionalQueryStringParams(null)
                                           .useBasicAuthenticationWithAccessCodeGrant(false).build();
    }

    /**
     * 描述
     * @return UiConfiguration
     */
    @Bean
    UiConfiguration uiConfig() {
        return UiConfigurationBuilder.builder().deepLinking(true).displayOperationId(false).defaultModelsExpandDepth(1)
                                     .defaultModelExpandDepth(1).defaultModelRendering(ModelRendering.EXAMPLE)
                                     .displayRequestDuration(false).docExpansion(DocExpansion.NONE).filter(false)
                                     .maxDisplayedTags(null).operationsSorter(OperationsSorter.ALPHA)
                                     .showExtensions(false).tagsSorter(TagsSorter.ALPHA).validatorUrl(null).build();
    }

    /**
     * 描述
     * @return OAuth
     */
    private OAuth securitySchema() {
        List<AuthorizationScope> authorizationScopes = new ArrayList<>(16);
        authorizationScopes.add(new AuthorizationScope("read","read all"));
        authorizationScopes.add(new AuthorizationScope("write","access all"));
        List<GrantType> grantTypes = new ArrayList<>(16);
        return new OAuth("oauth2",authorizationScopes,grantTypes);
    }

    /**
     * 描述
     * @return SecurityContext
     */
    private static SecurityContext securityContext() {
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }

    /**
     * 描述
     * @return List<SecurityReference>
     */
    private static List<SecurityReference> defaultAuth() {
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[3];
        authorizationScopes[0] = new AuthorizationScope("read","read all");
        authorizationScopes[1] = new AuthorizationScope("trust","trust all");
        authorizationScopes[2] = new AuthorizationScope("write","write all");
        return Collections.singletonList(new SecurityReference("oauth2",authorizationScopes));
    }
}